package com.luojie.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.luojie.constant.MessageConstant;
import com.luojie.context.BaseContext;
import com.luojie.dto.OrderSubmitDto;
import com.luojie.dto.OrdersPaymentDTO;
import com.luojie.exception.OrderBusinessException;
import com.luojie.mapper.*;
import com.luojie.po.*;
import com.luojie.service.OrdersService;
import com.luojie.utils.WeChatPayUtil;
import com.luojie.vo.OrderPaymentVO;
import com.luojie.vo.OrderSubmitVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.beans.Transient;
import java.math.BigDecimal;
import java.time.LocalDateTime;


@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderDetailsMapper orderDetailsMapper;
    @Autowired
    private MatchesMapper matchesMapper;
    @Autowired
    private BallMapper ballMapper;
    @Autowired
    private WeChatPayUtil weChatPayUtil;
    @Autowired
    private UserMapper userMapper;
    /**
     * 用户下单
     *
     * @param orderSubmitDto
     * @return
     */

    @Override
    @Transient
    public OrderSubmitVo submitOrder(OrderSubmitDto orderSubmitDto) {
        //在比赛表中更新比赛人数

        Matches matches = matchesMapper.selectById(orderSubmitDto.getMatchesId());
        Ball ball = ballMapper.selectById(orderSubmitDto.getBallId(), orderSubmitDto.getMatchesId());
        if (matches.getStatus() != 1) {
            throw new RuntimeException("该比赛不能报名");
        }
        Integer numberParticipants = ball.getNumberParticipants();
        if (numberParticipants > ball.getTotalNumberParticipants()) {
            throw new RuntimeException("该项目已满员");
        }
        OrderSubmitVo orderSubmitVo = new OrderSubmitVo();
        if (matches.getPayMode() == 0) {
            orderSubmitVo.setUserName(matches.getUserName());
            orderSubmitVo.setPhone(matches.getPhone());
            return orderSubmitVo;
        }
        ball.setNumberParticipants(numberParticipants + 1);
        ballMapper.updateBall(ball);

        //向订单表插入一条数据
        Long UserId = BaseContext.getCurrentId();
        Order order = new Order();
        order.setOrderNumber(String.valueOf(System.currentTimeMillis()));
        order.setOrderTime(LocalDateTime.now());
        order.setStatus(1);
        order.setAmount(orderSubmitDto.getAmount());
        order.setRemark(orderSubmitDto.getRemark());
        order.setPhone(orderSubmitDto.getPhone());
        order.setAddress(matches.getAddress());
        order.setUserId(UserId);
        order.setCreatedTime(LocalDateTime.now());
        order.setUpdatedTime(LocalDateTime.now());
        ordersMapper.insert(order);
        //订单详情表插入一条数据
        OrderDetail orderDetails = new OrderDetail();
        orderDetails.setOrderId(order.getId());
        orderDetails.setMatchesId(orderSubmitDto.getMatchesId());
        orderDetails.setBallId(orderSubmitDto.getBallId());
        orderDetails.setMatchesName(matches.getName());
        orderDetails.setBallName(ball.getBallGamesName());
        orderDetails.setPrice(orderSubmitDto.getAmount());
        orderDetailsMapper.insert(orderDetails);
        //返回数据
        orderSubmitVo.setOrderNumber(String.valueOf(System.currentTimeMillis()));
        orderSubmitVo.setAmount(orderSubmitDto.getAmount());
        orderSubmitVo.setOrderTime(LocalDateTime.now());
        orderSubmitVo.setMatchesName(matches.getName());
        orderSubmitVo.setBallName(ball.getBallGamesName());


        return orderSubmitVo;

    }

    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception{
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getById(userId);
        Order order = ordersMapper.getByNumberAndUserId(ordersPaymentDTO.getOrderNumber(),userId);
        //调用微信支付接口，生成预支付交易单
        JSONObject jsonObject = weChatPayUtil.pay(
                ordersPaymentDTO.getOrderNumber(), //商户订单号
                order.getAmount(), //支付金额，单位 元
                "罗杰体育订单", //商品描述
                user.getOpenid() //微信用户的openid
        );

        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }

        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        vo.setPackageStr(jsonObject.getString("package"));

        return vo;
    }
    /**
     * 支付成功，修改订单状态
     *
     * @param outTradeNo
     */

    @Transient
    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        // 根据订单号查询当前用户的订单
        Order ordersDB = ordersMapper.getByNumberAndUserId(outTradeNo, userId);
        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Order orders =  new Order();
        orders.setId(ordersDB.getId());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setStatus(2);
        orders.setPayStatus(Order.PAID);
        ordersMapper.update(orders);

    }
    @Transient
    @Override
    public void userCancelById(Long id,OrderSubmitDto orderSubmitDto) {
        // 根据id查询订单
        Order ordersDB = ordersMapper.geById(id);

        // 校验订单是否存在
        if (ordersDB == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
        if (ordersDB.getStatus() > 2) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        Order orders = new Order();
        orders.setId(ordersDB.getId());
        Double dbAmount = ordersDB.getAmount().doubleValue();// 订单处于待接单状态下取消，需要进行退款
        if (ordersDB.getStatus().equals(6)) {
            //调用微信支付退款接口
            try {
                weChatPayUtil.refund(
                        ordersDB.getOrderNumber(), //商户订单号
                        ordersDB.getOrderNumber(), //商户退款单号
                        orders.getAmount(),//退款金额，单位 元
                        new BigDecimal(dbAmount));//原订单金额
            } catch (Exception e) {
                e.printStackTrace();
            }

            //支付状态修改为 退款
            orders.setPayStatus(Order.REFUND);
        }

        Ball ball = ballMapper.selectById(orderSubmitDto.getBallId(), orderSubmitDto.getMatchesId());
        ball.setNumberParticipants(ball.getNumberParticipants() - 1);
        ballMapper.updateBall(ball);
        // 更新订单状态
        orders.setStatus(6);
        ordersMapper.update(orders);
    }

}
